{ config, pkgs, inputs, ... }:
let
  user = "slark";
in {
  imports = with inputs.self.modules; [
    ./disko.nix

    domains."fail2banana.ru"
  ];

  documentation = {
    doc.enable = false;
    man.enable = false;
    nixos.enable = false;
  };

  nixpkgs.hostPlatform = "x86_64-linux";

  boot = {
    initrd = {
      availableKernelModules = [
        "uhci_hcd" "ehci_pci" "ata_piix" "ahci" "firewire_ohci"
        "pata_jmicron" "usb_storage" "usbhid" "floppy" "sd_mod" "sr_mod"
      ];
      kernelModules = [ "kvm-intel" ];
    };
    loader = {
      grub = {
        enable = true;
        memtest86.enable = true;
      };
      timeout = 2;
    };
    zfs.devNodes = "/dev/disk/by-partlabel";
  };

  environment.persistence."/system/persist" = {
    directories = [
      "/etc/ssh"
      "/var/backup"
      "/var/db/sudo"
      "/var/lib"
      "/var/log"
    ];
    files = [
      "/etc/machine-id"
    ];
  };

  fileSystems = {
    "/etc/ssh" = {
      depends = [ "/system" ];
      neededForBoot = true;
    };
    "/system".neededForBoot = true;
  };

  age.secrets = with inputs.self.modules; {
    blackberry-wg0.file = secrets.blackberry-wg0;
    yama-wg0-blackberry.file = secrets.yama-wg0-blackberry;
  };

  networking = {
    hostId = "51a82d4c";
    hostName = "blackberry";
    dhcpcd.enable = true;
    useDHCP = true;

    firewall.allowedUDPPorts = [ 41820 ];

    wireguard.interfaces = {
      wg0 = {
        ips = [ "10.0.0.50/24" ];
        listenPort = 41820;
        privateKeyFile = config.age.secrets.blackberry-wg0.path;
        peers = [
          { # yama
            publicKey = "Tan9IHvGvzeHFBSg3ZnhqNuJFYtAB+hfybbh9SPWRwk=";
            presharedKeyFile = config.age.secrets.yama-wg0-blackberry.path;
            allowedIPs = [ "10.0.0.1/32" ];
          }
        ];
      };
    };
  };

  security = {
    polkit.extraConfig = ''
      polkit.addRule(function(action, subject) {
        if (subject.active && subject.isInGroup("wheel"))
          return polkit.Result.YES;
      });
    '';
    sudo.wheelNeedsPassword = false;
  };

  environment.etc = {
    "fail2ban/filter.d/nextcloud.local".text = ''
      [Definition]
      _groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
      failregex = ^.*\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
                  ^.*\{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
      datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
    '';
    "fail2ban/filter.d/vaultwarden.local".text = ''
      [Definition]
      failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username: <F-USER>.*</F-USER>\.$
      ignoreregex =
    '';
  };

  programs.atop.netatop.enable = true;

  services = {
    btrfs.autoScrub = {
      enable = true;
      fileSystems = [ "/system" ];
    };
    fail2ban = {
      enable = true;
      bantime-increment.enable = true;
      ignoreIP = [ "192.168.0.0/16" ];
      jails = {
        nextcloud.settings = {
          backend = "systemd";
          bantime = 600;
          filter = "nextcloud";
          findtime = 600;
          port = "443";
          protocol = "tcp";
        };
        vaultwarden.settings = {
          backend = "systemd";
          bantime = 600;
          filter = "vaultwarden";
          findtime = 600;
          port = "443";
          protocol = "tcp";
        };
      };
    };
    openssh.enable = true;
    postgresql.package = pkgs.postgresql_16;
    postgresqlBackup = {
      enable = true;
      compression = "zstd";
      startAt = "04:00";
    };
    restic.backups.localbackup = {
      exclude = [ "all.prev.sql.zstd" ];
      initialize = true;
      passwordFile = "/data/secrets/restic-password";
      paths = [
        config.services.postgresqlBackup.location
      ];
      pruneOpts = [ "--keep-last 60" ];
      repository = "/data/backups";
      timerConfig = {
        OnCalendar = "04:30";
        Persistent = true;
      };
    };
    zfs.autoScrub = {
      enable = true;
      pools = [ "datapool" ];
    };
  };

  zramSwap.enable = true;

  users.users = {
    ${user} = {
      extraGroups = [ "wheel" "audio" "video" ];
      initialPassword = user;
      isNormalUser = true;
      openssh.authorizedKeys.keys = import inputs.self.modules.keys.aya;
    };
    root.initialPassword = user;
  };

  home-manager.users.${user} = {};
}
